#!/usr/bin/perl

# Copyright (C) Intel, Inc.
# (C) Sergey Kandaurov
# (C) Nginx, Inc.

# Tests for http resolver, worker process termination.

###############################################################################

use warnings;
use strict;

use Test::More;

BEGIN { use FindBin; chdir($FindBin::Bin); }

use lib 'lib';
use Test::Nginx;

###############################################################################

select STDERR; $| = 1;
select STDOUT; $| = 1;

my $t = Test::Nginx->new()->has(qw/http proxy/);

plan(skip_all => 'win32') if $^O eq 'MSWin32';

$t->write_file_expand('nginx.conf', <<'EOF')->plan(1);

%%TEST_GLOBALS%%

daemon off;

events {
}

http {
    %%TEST_GLOBALS_HTTP%%

    server {
        listen       127.0.0.1:8080;
        server_name  localhost;

        location / {
            resolver 127.0.0.1:%%PORT_8981_UDP%%;
            proxy_pass http://example.net/$args;
        }

        location /pid {
            add_header X-Pid $pid always;
        }
    }
}

EOF

$t->run_daemon(\&dns_daemon, $t);
$t->run()->waitforfile($t->testdir . '/' . port(8981));

###############################################################################

# truncated UDP response, no response over TCP

my $s = http_get('/', start => 1);

pass('request');

sleep 1;

# retrasmission timer wasn't removed during resolver cleanup,
# while the event memory was freed, resulting in use-after-free
# when later removing timer in TCP connection

http_get('/pid') =~ qr/X-Pid: (\d+)/;
kill 'TERM', $1;

###############################################################################

sub dns_daemon {
    my ($t) = @_;
    my ($data);

    my $socket = IO::Socket::INET->new(
        LocalAddr => '127.0.0.1',
        LocalPort => port(8981),
        Proto => 'udp',
    )
        or die "Can't create UDP socket: $!\n";

    # signal we are ready

    open my $fh, '>', $t->testdir() . '/' . port(8981);
    close $fh;

    while (1) {
        $socket->recv($data, 65536);
        # truncation bit set
        $data |= pack("n2", 0, 0x8380);
        $socket->send($data);
    }
}

###############################################################################
